package cn.schoolwow.workflow.module.task.query.flow;

import cn.schoolwow.quickdao.domain.DAO;
import cn.schoolwow.quickdao.domain.database.dql.condition.Condition;
import cn.schoolwow.quickdao.domain.database.dql.subCondition.SubCondition;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.workflow.domain.task.ContextDataQuery;
import cn.schoolwow.workflow.domain.task.WorkFlowTaskQuery;
import cn.schoolwow.workflow.entity.*;

public class SetTaskQueryConditionFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        setCondition(flowContext);
        setWorkFlowInstanceSubCondition(flowContext);
        setWorkFlowDefinitionSubCondition(flowContext);
        setWorkFlowNodeSubCondition(flowContext);
        setWorkFlowCarbonCopySubCondition(flowContext);
    }

    @Override
    public String name() {
        return "设置工作流任务查询对象";
    }

    private void setCondition(FlowContext flowContext){
        DAO dao = flowContext.checkInstanceData(DAO.class);
        WorkFlowTaskQuery workFlowTaskQuery = flowContext.checkInstanceData(WorkFlowTaskQuery.class);

        Condition condition = dao.query(WorkFlowTask.class)
                .orderByDesc("createdAt")
                .addQuery("hidden", false)
                .addColumnAs("id", "taskId")
                .addColumnAs("taskName", "taskName")
                .addColumnAs("complete", "complete")
                .addColumnAs("createdAt", "taskCreatedTime");
        if(null!=workFlowTaskQuery.taskIdList &&!workFlowTaskQuery.taskIdList.isEmpty()){
            condition.addInQuery("id", workFlowTaskQuery.taskIdList);
        }
        if(null!=workFlowTaskQuery.instanceIdList &&!workFlowTaskQuery.instanceIdList.isEmpty()){
            condition.addInQuery("instanceId", workFlowTaskQuery.instanceIdList);
        }
        if(!workFlowTaskQuery.assignerList.isEmpty()){
            condition.addInQuery("assigner", workFlowTaskQuery.assignerList);
        }
        if(null!=workFlowTaskQuery.complete){
            condition.addQuery("complete", workFlowTaskQuery.complete);
        }
        if(null!=workFlowTaskQuery.submitTimeDuration){
            if(null!=workFlowTaskQuery.submitTimeDuration.startTime){
                condition.addQuery("createdAt", ">=", workFlowTaskQuery.submitTimeDuration.startTime);
            }
            if(null!=workFlowTaskQuery.submitTimeDuration.endTime){
                condition.addQuery("createdAt", "<=", workFlowTaskQuery.submitTimeDuration.endTime);
            }
        }
        if(null!=workFlowTaskQuery.finishTimeDuration){
            if(null!=workFlowTaskQuery.finishTimeDuration.startTime){
                condition.addQuery("updatedAt", ">=", workFlowTaskQuery.finishTimeDuration.startTime);
            }
            if(null!=workFlowTaskQuery.finishTimeDuration.endTime){
                condition.addQuery("updatedAt", "<=", workFlowTaskQuery.finishTimeDuration.endTime);
            }
        }
        flowContext.putInstanceData(condition, Condition.class);
    }

    //关联工作流实例
    private void setWorkFlowInstanceSubCondition(FlowContext flowContext){
        Condition condition = flowContext.checkInstanceData(Condition.class);
        WorkFlowTaskQuery workFlowTaskQuery = flowContext.checkInstanceData(WorkFlowTaskQuery.class);

        SubCondition workFlowInstanceSubCondition = condition.joinTable(WorkFlowInstance.class, "instanceId", "id")
                .addColumnAs("id","instanceId")
                .addColumnAs("definitionId","definitionId")
                .addColumnAs("initiator","initiator")
                .addColumnAs("contextData", "contextData")
                .addColumnAs("name", "instanceName")
                .addColumnAs("status", "instanceStatus")
                .addColumnAs("createdAt", "instanceCreatedTime");
        if(null!=workFlowTaskQuery.instanceStatusList &&!workFlowTaskQuery.instanceStatusList.isEmpty()){
            workFlowInstanceSubCondition.addInQuery("status", workFlowTaskQuery.instanceStatusList);
        }
        if(!workFlowTaskQuery.instanceIdList.isEmpty()){
            workFlowInstanceSubCondition.addInQuery("id", workFlowTaskQuery.instanceIdList);
        }
        if(!workFlowTaskQuery.instanceNameList.isEmpty()){
            workFlowInstanceSubCondition.addInQuery("name", workFlowTaskQuery.instanceNameList);
        }
        if(!workFlowTaskQuery.initiatorList.isEmpty()){
            workFlowInstanceSubCondition.addInQuery("initiator", workFlowTaskQuery.initiatorList);
        }
        for(ContextDataQuery contextDataQuery: workFlowTaskQuery.contextDataQueryList){
            workFlowInstanceSubCondition.addJSONQuery("contextData", contextDataQuery.fieldName,contextDataQuery.operator,contextDataQuery.value);
        }
        flowContext.putTemporaryData("workFlowInstanceSubCondition", workFlowInstanceSubCondition);
    }

    //关联流程定义
    private void setWorkFlowDefinitionSubCondition(FlowContext flowContext){
        SubCondition workFlowInstanceSubCondition = (SubCondition) flowContext.checkData("workFlowInstanceSubCondition");
        WorkFlowTaskQuery workFlowTaskQuery = flowContext.checkInstanceData(WorkFlowTaskQuery.class);

        SubCondition workFlowDefinitionSubCondition = workFlowInstanceSubCondition.joinTable(WorkFlowDefinition.class, "definitionId", "id")
                .addColumnAs("name", "definitionName");
        if(!workFlowTaskQuery.definitionIdList.isEmpty()){
            workFlowDefinitionSubCondition.addInQuery("id", workFlowTaskQuery.definitionIdList);
        }
        if(!workFlowTaskQuery.definitionNameList.isEmpty()){
            workFlowDefinitionSubCondition.addInQuery("name", workFlowTaskQuery.definitionNameList);
        }
        flowContext.putTemporaryData("workFlowDefinitionSubCondition", workFlowDefinitionSubCondition);
    }

    //关联流程节点
    private void setWorkFlowNodeSubCondition(FlowContext flowContext){
        Condition condition = flowContext.checkInstanceData(Condition.class);
        WorkFlowTaskQuery workFlowTaskQuery = flowContext.checkInstanceData(WorkFlowTaskQuery.class);

        SubCondition workFlowNodeSubCondition = condition.joinTable(WorkFlowNode.class, "nodeId", "id");
        if(!workFlowTaskQuery.nodeNameList.isEmpty()){
            workFlowNodeSubCondition.addInQuery("name", workFlowTaskQuery.nodeNameList);
        }
        flowContext.putTemporaryData("workFlowNodeSubCondition", workFlowNodeSubCondition);
    }

    private void setWorkFlowCarbonCopySubCondition(FlowContext flowContext){
        WorkFlowTaskQuery workFlowTaskQuery = flowContext.checkInstanceData(WorkFlowTaskQuery.class);
        if(workFlowTaskQuery.carbonCopyList.isEmpty()){
            return;
        }

        SubCondition workFlowInstanceSubCondition = flowContext.checkData("workFlowInstanceSubCondition", SubCondition.class);
        SubCondition workFlowInstanceCarbonCopySubCondition = workFlowInstanceSubCondition.joinTable(WorkFlowInstanceCarbonCopy.class, "id", "instanceId");
        workFlowInstanceCarbonCopySubCondition.addInQuery("carbonCopy",workFlowTaskQuery.carbonCopyList);
        flowContext.putTemporaryData("workFlowInstanceCarbonCopySubCondition", workFlowInstanceCarbonCopySubCondition);
    }
}
